local task = {}

---类型声明
do
    ---任务条件
    ---@class TASKCONDITION
    ---@field form string 事件类型
    ---@field tar_count integer 目标次数

    ---任务奖励
    ---@class TASKREWARDREWARD
    ---@field exp integer 奖励经验数量
    ---@field event string 奖励执行的事件名称

    ---任务数据
    ---@class TASKDATA
    ---@field name string 任务名称
    ---@field weight integer 任务权重
    ---@field kind integer 任务类型
    ---@field desc string 任务描述
    ---@field condition TASKCONDITION[] 任务条件
    ---@field reward TASKREWARDREWARD 任务条件

    ---任务集数据
    ---@class TASKSDATA
    ---@field name string 任务集名称
    ---@field list TASKDATA[] 任务列表
end

-- 常量定义（只读）
local TASKTYPE_LITERAL <const> = { "主线", "日常", "节日", "活动" }

---任务类型
do
    ---@class TaskType
    ---@field id integer @类型ID (1=主线, 2=日常,...)
    task.TaskType = {}
    task.TaskType.__index = task.TaskType

    ---@param id integer
    ---@return TaskType
    function task.TaskType.new(id)
        local self = setmetatable({}, task.TaskType)
        self.id = id
        return self
    end

    function task.TaskType:__tostring()
        return TASKTYPE_LITERAL[self.id] or ("未知类型(ID: " .. self.id .. ")")
    end
end

---任务类
do
    ---@class Task
    ---@field name string
    ---@field desc string
    ---@field weight integer
    ---@field kind TaskType
    ---@field ctrl_tasks Tasks
    ---@field is_complete boolean
    ---@field reward_complete boolean
    ---@field if_complete function[]
    ---@field cur_count integer[]
    ---@field tar_count integer[]
    ---@field order integer
    task.Task = {}
    task.Task.__index = task.Task

    --构造任务实例
    ---@param name string
    ---@param weight integer
    ---@param kind TaskType
    ---@param desc string
    ---@return Task
    function task.Task.new(name, weight, kind, desc)
        local self = setmetatable({}, task.Task)
        self.name = name
        self.desc = desc
        self.weight = weight
        self.kind = kind
        self.is_complete = false
        self.reward_complete = false
        self.if_complete = {}
        self.order = 0
        return self
    end

    ---检查任务是否完成
    ---@return boolean
    function task.Task:check()
        for i = 1, #self.cur_count do
            if self.cur_count[i] < self.tar_count[i] then
                return false
            end
        end
        self.is_complete = true
        return true
    end

    ---完成任务
    function task.Task:done()
        for _, complete in ipairs(self.if_complete) do
            complete(self.ctrl_tasks.ctrl_role)
        end
        LuaAPI.global_send_event(
            { EVENT.CUSTOM_EVENT, "通用任务完成" },
            {
                ["完成者"] = self.ctrl_tasks.ctrl_role,
                ["任务编号"] = math.tointeger(self.order)
            }
        )
    end

    ---领取任务奖励
    function task.Task:get_reward()
        if not self.is_complete then
            return
        end
        if not self.reward_complete then
            self.reward_complete = true
            self:done()
        end
    end

    ---任务加分
    ---@param exp_order integer 条件编号
    ---@param score integer 分数
    function task.Task:add_score(exp_order, score)
        self.cur_count[exp_order] = self.cur_count[exp_order] + score
        self:check()
    end
end

---任务集类
do
    ---@class Tasks
    ---@field name string
    ---@field list Task[] | table
    ---@field ctrl_role Role
    ---@field order integer
    ---@field page integer
    ---@field tag ENode
    ---@field page_tag ENode
    ---@field icons Enums.ValueType.ListEImage
    ---@field units ListENode
    ---@field names ListELabel
    ---@field descs ListELabel
    ---@field counts ListELabel
    task.Tasks = {}
    task.Tasks.__index = task.Tasks

    ---构造任务集
    ---@param binder Role
    ---@return Tasks
    function task.Tasks.new(binder)
        local self = setmetatable({}, task.Tasks)
        self.ctrl_role = binder
        self.list = {}
        self.page = 1
        return self
    end

    ---展示任务集
    ---@param page integer
    function task.Tasks:display(page)
        -- 初始化值
        self.page = page
        local total_length = #self.names ---@type integer
        local start_index = (page - 1) * total_length ---@type integer
        local _role = self.ctrl_role
        local _max_page = #self.list // #self.names + 1

        _role.set_label_text(self.page_tag, string.format("%d / %d", math.tointeger(page), math.tointeger(_max_page)))
        -- 更新图标
        for i = 1, total_length do
            ---声明定义控件
            local index = start_index + i
            local _unit = self.units[i]
            if index > #self.list then
                _role.set_node_visible(_unit, false)
            else
                _role.set_node_visible(_unit, true)
                local _task = self.list[index]
                -- local icon = self.icons[i]
                local name = self.names[i]
                local desc = self.descs[i]
                local count = self.counts[i]
                local _cur_count = 0
                local _tar_count = 0
                for x = 1, #_task.cur_count do
                    _cur_count = _cur_count + _task.cur_count[x]
                    _tar_count = _tar_count + _task.tar_count[x]
                end
                ---更新控件内容
                _role.set_label_text(name, _task.name)
                _role.set_label_text(desc, _task.desc)
                _role.set_label_color(count, 0, 0)
                _role.set_label_text(count, string.format("%d / %d", _cur_count, _tar_count))
                ---条件判断
                if _task.is_complete and (not _task.reward_complete) then
                    _role.set_label_color(count, 16766720, 0)
                    _role.set_label_text(count, "可领取")
                elseif _task.reward_complete then
                    _role.set_label_color(count, 65280, 0)
                    _role.set_label_text(count, "已完成")
                end
            end
        end
    end

    ---导入任务集
    ---@param content TASKSDATA
    function task.Tasks:import(content)
        self.name = content.name
        for _, task_info in ipairs(content.list) do
            local _task = task.Task.new(
                task_info.name,
                task_info.weight,
                task.TaskType.new(task_info.kind),
                task_info.desc
            )

            _task.ctrl_tasks = self
            ---初始化任务完成条件
            for _, condition in ipairs(task_info.condition) do
                local form = condition.form
                if form == EVENT.CUSTOM_EVENT then ---当前任务以自定义的方式完成
                    _task.cur_count = { 0 }
                    _task.tar_count = { condition.tar_count }
                end
            end

            local reward = task_info.reward
            if rawget(reward, "exp") then
                table.insert(
                    _task.if_complete,
                    function()
                        LuaAPI.global_send_event(
                            { EVENT.CUSTOM_EVENT, "给予经验" },
                            {
                                ["获得者"] = self.ctrl_role,
                                ["经验数量"] = math.tointeger(task_info.reward.exp)
                            }
                        )
                    end
                )
            end

            if rawget(reward, "event") then
                table.insert(
                    _task.if_complete,
                    function()
                        LuaAPI.global_send_event(
                            { EVENT.CUSTOM_EVENT, reward.event },
                            { ["获得者"] = self.ctrl_role }
                        )
                    end
                )
            end

            table.insert(self.list, _task)
            _task.order = self.order * 10000 + #self.list
        end
    end
end

return task
